﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using Kooboo.HtmlFunc;
using Kooboo.HtmlFunc.Providers;
using Kooboo.CMS.SiteConverter.Providers;

namespace Kooboo.CMS.SiteConverter.Parser.Razor
{
    public class LayoutParser : ParserBase, IParser<ILayout>
    {
        public static HtmlNode FindHead(HtmlDocument document)
        {
            var htmlNode = document.DocumentNode.ChildNodes.FindTag("HTML");
            if (htmlNode == null) { return null; }
            return htmlNode.ChildNodes.FindTag("HEAD");
        }

        public static HtmlNode FindBody(HtmlDocument document)
        {
            var htmlNode = document.DocumentNode.ChildNodes.FindTag("HTML");
            if (htmlNode == null) { return null; }
            return htmlNode.ChildNodes.FindTag("BODY");
        }

        public static void AppendHead(HtmlDocument document, HtmlNode node)
        {
            // first choice
            var head = FindHead(document);
            if (head != null)
            {
                head.AppendChild(node);
                return;
            }

            // second choice
            var body = FindBody(document);
            if (body != null)
            {
                var firstChild = body.ChildNodes.FirstElement();
                if (firstChild != null)
                {
                    body.InsertBefore(node, firstChild);
                }
                else
                {
                    body.AppendChild(node);
                }
                return;
            }

            // last choice
            if (document.DocumentNode.ChildNodes.Count > 0)
            {
                document.DocumentNode.InsertBefore(node, document.DocumentNode.ChildNodes[0]);
            }
            else
            {
                document.DocumentNode.AppendChild(node);
            }
        }

        public static void AppendToBody(HtmlDocument document, HtmlNode node)
        {
            // first choice
            var body = FindBody(document);
            if (body != null)
            {
                body.AppendChild(node);
                return;
            }

            // last choice
            document.DocumentNode.AppendChild(node);
        }

        public static void FillResult(ILayout obj, IParseResult result, string engineName)
        {
            result.Layout.EngineName = engineName;
            result.Layout.Name = obj.Name;
            result.Layout.Body = obj.Document.ReadString();
        }

        #region IParser<ILayout> Members

        public void Parse(ILayout obj)
        {
            // head
            var markup = new StringBuilder();
            markup.AppendLine("    @Html.FrontHtml().Title()");
            markup.AppendLine("    @Html.FrontHtml().Meta()");
            markup.AppendLine("    @Html.FrontHtml().RegisterStyles()");
            var markupNode = NodeExtension.CreateNode(markup.ToString());
            AppendHead(obj.Document, markupNode);

            // script
            var scriptNode = NodeExtension.CreateNode("    @Html.FrontHtml().RegisterScripts()" + Environment.NewLine);
            AppendToBody(obj.Document, scriptNode);

            // result
            FillResult(obj, this.Context.Result, this.EngineName);
        }

        #endregion
    }
}
